package com.cqupt.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cqupt.exception.BusinessException;
import com.cqupt.model.constant.Constant;
import com.cqupt.model.dto.UserLoginDto;
import com.cqupt.model.dto.UserRegisterDto;
import com.cqupt.model.pojo.SysUser;
import com.cqupt.model.vo.ImageCheck;
import com.cqupt.model.vo.ResultCodeEnum;
import com.cqupt.service.FileService;
import com.cqupt.service.SparkService;
import com.cqupt.service.SysUserService;
import com.cqupt.mapper.SysUserMapper;
import com.cqupt.utils.AuthContextUtil;
import jakarta.annotation.Resource;
import org.bouncycastle.crypto.digests.MD5Digest;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.TimeUnit;


@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
        implements SysUserService {


    @Resource
    private SysUserMapper sysUserMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private FileService fileService;

    @Resource
    private SparkService sparkService;

    @Override
    public String login(UserLoginDto userLoginDto) {

        String phone = userLoginDto.getPhone();
        String password = userLoginDto.getPassword();
        password = DigestUtils.md5DigestAsHex(password.getBytes());

        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getPhone, phone);
        SysUser sysUser = sysUserMapper.selectOne(wrapper);

        if (Objects.isNull(sysUser)) {
            throw new BusinessException(ResultCodeEnum.LOGIN_ERROR);
        }
        if (!sysUser.getPassword().equals(password)) {
            throw new BusinessException(ResultCodeEnum.LOGIN_ERROR);
        }
        if (sysUser.getIsDeleted() == Constant.DISABLED_STATE) {
            throw new BusinessException(ResultCodeEnum.ACCOUNT_STOP);
        }

        String token = UUID.randomUUID().toString().replaceAll("-", "");
        String jsonUser = JSON.toJSONString(sysUser);
        stringRedisTemplate.opsForValue().set(Constant.REDIS_TOKEN_KEY + token, jsonUser, Constant.DEFAULT_TOKEN_EXPIRE_TIME, TimeUnit.DAYS);

        return token;
    }

    @Override
    public String login2(UserLoginDto userLoginDto) {
        String phone = userLoginDto.getPhone();
        String code = userLoginDto.getCode();
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getPhone, phone);
        SysUser sysUser = sysUserMapper.selectOne(wrapper);
        String redisCode = stringRedisTemplate.opsForValue().get(phone);
        if (StrUtil.isEmpty(redisCode) || !redisCode.equals(code)) {
            throw new BusinessException(ResultCodeEnum.CODE_EXPIRED);
        }
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        if (Objects.isNull(sysUser)) {
            SysUser user = new SysUser();
            user.setPhone(phone);
            user.setPassword(DigestUtils.md5DigestAsHex(phone.getBytes()));
            user.setNickname(UUID.randomUUID().toString().substring(0,6));
            user.setAvatar("http://127.0.0.1:9000/app-bucket/avatar.jpeg");
            sysUserMapper.insert(user);
            String jsonUser = JSON.toJSONString(sysUserMapper.selectOne(wrapper));
            stringRedisTemplate.opsForValue().set(Constant.REDIS_TOKEN_KEY + token, jsonUser, Constant.DEFAULT_TOKEN_EXPIRE_TIME, TimeUnit.DAYS);
        } else {
            String jsonUser = JSON.toJSONString(sysUser);
            stringRedisTemplate.opsForValue().set(Constant.REDIS_TOKEN_KEY + token, jsonUser, Constant.DEFAULT_TOKEN_EXPIRE_TIME, TimeUnit.DAYS);
        }
//        if (sysUser.getIsDeleted() == Constant.DISABLED_STATE) {
//            stringRedisTemplate.delete(phone);
//            throw new BusinessException(ResultCodeEnum.ACCOUNT_STOP);
//        }
        stringRedisTemplate.delete(phone);
        return token;
    }

    @Override
    public void register(UserRegisterDto userRegisterDto) {
        String phone = userRegisterDto.getPhone();
        String password = userRegisterDto.getPassword();
        String confirmPassword = userRegisterDto.getConfirmPassword();
        String code = userRegisterDto.getCode();
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getPhone, phone);
        SysUser sysUser = sysUserMapper.selectOne(wrapper);
        if (!Objects.isNull(sysUser)) {
            if (sysUser.getIsDeleted() == Constant.ENABLED_STATE)
                throw new BusinessException(ResultCodeEnum.USER_NAME_IS_EXISTS);
        }
        if (!password.equals(confirmPassword)) {
            throw new BusinessException(ResultCodeEnum.PWD_IS_NOT_SAME);
        }
        String redisCode = stringRedisTemplate.opsForValue().get(phone);
        if (StrUtil.isEmpty(redisCode)) {
            throw new BusinessException(ResultCodeEnum.CODE_EXPIRED);
        }
        if (!redisCode.equals(code)) {
            throw new BusinessException(ResultCodeEnum.CODE_EXPIRED);
        }

        password = DigestUtils.md5DigestAsHex(password.getBytes());

        if (!Objects.isNull(sysUser)) {
            if (sysUser.getIsDeleted() == Constant.DISABLED_STATE) {
                sysUser.setIsDeleted(Constant.ENABLED_STATE);
                sysUser.setPassword(password);
                sysUserMapper.updateById(sysUser);
                // TODO
//                stringRedisTemplate.delete(phone);
                return;
            }
        }

        SysUser user = new SysUser();
        user.setPhone(phone);
        user.setPassword(password);
        user.setNickname(UUID.randomUUID().toString().substring(0,6));
        user.setAvatar("http://127.0.0.1:9000/app-bucket/avatar.jpeg");
        sysUserMapper.insert(user);
        // TODO
//        stringRedisTemplate.delete(phone);
    }

    @Override
    public String updateAvatar(MultipartFile file) {
        String json = sparkService.checkImageCompliance(file);
        JSONObject jsonObject = JSON.parseObject(json);
        JSONObject resultObject = jsonObject.getJSONObject("data").getJSONObject("result");
        String suggest = resultObject.getString("suggest");
        if (!suggest.equals("pass")) {
            throw new BusinessException(ResultCodeEnum.IMAGE_ILLEGAL);
        }
        String new_avatar = fileService.upload(file);

        SysUser sysUser = AuthContextUtil.get();
        sysUser.setAvatar(new_avatar);
        sysUser.setUpdateTime(new Date());
        sysUserMapper.updateById(sysUser);
        return new_avatar;
    }

    @Override
    public void updateNickname(String nickname) {
        String json = sparkService.checkText(nickname);
        JSONObject jsonObject = JSON.parseObject(json);
        JSONObject resultObject = jsonObject.getJSONObject("data").getJSONObject("result");
        String suggest = resultObject.getString("suggest");
        if (!suggest.equals("pass")) {
            throw new BusinessException(ResultCodeEnum.TEXT_ILLEGAL);
        }
        SysUser sysUser = AuthContextUtil.get();
        sysUser.setNickname(nickname);
        sysUser.setUpdateTime(new Date());
        sysUserMapper.updateById(sysUser);
    }

    @Override
    public void logout(String token) {
        stringRedisTemplate.delete(Constant.REDIS_TOKEN_KEY + token);
    }

    @Override
    public void updateSex(int sex) {
        Integer userId = AuthContextUtil.get().getId();
        SysUser sysUser = sysUserMapper.selectById(userId);
        if (ObjectUtil.isNotNull(sysUser)) {
            sysUser.setSex(sex);
            sysUserMapper.updateById(sysUser);
        }
    }

    @Override
    public SysUser userInfo() {
        Integer userId = AuthContextUtil.get().getId();

        return sysUserMapper.selectById(userId);
    }

    @Override
    public void updateBirth(String birth) {
        Integer userId = AuthContextUtil.get().getId();
        SysUser sysUser = sysUserMapper.selectById(userId);
        if (ObjectUtil.isNotNull(sysUser)) {
            sysUser.setBirth(birth);
            sysUserMapper.updateById(sysUser);
        }
    }

    @Override
    public String login3(String phone) {
        LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getPhone, phone);
        SysUser sysUser = sysUserMapper.selectOne(wrapper);
        String token = UUID.randomUUID().toString().replaceAll("-", "");
        if (ObjectUtil.isNull(sysUser)) {
            SysUser user = new SysUser();
            user.setPhone(phone);
            user.setPassword(DigestUtils.md5DigestAsHex(phone.getBytes()));
            user.setNickname(UUID.randomUUID().toString().substring(0,6));
            user.setAvatar("http://127.0.0.1:9000/app-bucket/avatar.jpeg");
            sysUserMapper.insert(user);
            String jsonUser = JSON.toJSONString(sysUserMapper.selectOne(wrapper));
            stringRedisTemplate.opsForValue().set(Constant.REDIS_TOKEN_KEY + token, jsonUser, Constant.DEFAULT_TOKEN_EXPIRE_TIME, TimeUnit.DAYS);
        } else {
            String jsonUser = JSON.toJSONString(sysUser);
            stringRedisTemplate.opsForValue().set(Constant.REDIS_TOKEN_KEY + token, jsonUser, Constant.DEFAULT_TOKEN_EXPIRE_TIME, TimeUnit.DAYS);
        }
        return token;
    }
}




